package org.heda.mojos;

/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * Goal which touches a timestamp file.
 */
@Mojo(name = "generate", defaultPhase = LifecyclePhase.INSTALL)
public class GenerateDeployMojo extends AbstractMojo {

    @Parameter(defaultValue = "${project.basedir}")
    private File basedir;

    private File deployDir;
    private File packageXml;
    private File dockerSh;
    private File dockerfile;
    private File springSh;

    @Parameter(defaultValue = "${project.build.finalName}")
    private String finalName;

    @Parameter(defaultValue = "${project.packaging}")
    private String packaging;

    /**
     * springboot 端口
     */
    @Parameter(defaultValue = "8080")
    private String serverPort;

    /**
     * springboot contextPath
     */
    @Parameter(defaultValue = "/")
    private String contextPath;

    public void execute() throws MojoExecutionException {
        try {
            this.init();
            this.generate();
        } catch (Exception e) {
            this.getLog().info(e.getMessage(), e);
        }
    }

    public void init() {

        this.deployDir = FileUtil.file(basedir + File.separator + "deploy");
        this.packageXml = FileUtil.file(deployDir + File.separator + "package.xml");
        this.dockerSh = FileUtil.file(deployDir + File.separator + "docker.sh");
        this.dockerfile = FileUtil.file(deployDir + File.separator + "Dockerfile");
        this.springSh = FileUtil.file(deployDir + File.separator + "spring.sh");

        FileUtil.clean(deployDir);
        FileUtil.mkdir(deployDir);
        FileUtil.touch(packageXml);
        FileUtil.touch(dockerSh);
        FileUtil.touch(dockerfile);
        FileUtil.touch(springSh);

    }

    public void generate() {
        this.generatePackage();
        this.generateDocker();
        this.generateDockerfile();
        this.generateSpring();
    }

    public void generatePackage() {
        if (FileUtil.exist(packageXml)) {
            String str = this.readFile("package.xml");
            FileUtil.writeUtf8String(str, packageXml);
        }
    }

    public void generateDocker() {
        if (FileUtil.exist(dockerSh)) {
            String str = this.readFile("docker.sh");
            str = StrUtil.replace(str, "${server.port}", serverPort);
            str = StrUtil.replace(str, "${project.build.finalName}", finalName);
            FileUtil.writeUtf8String(str, dockerSh);
        }
    }

    public void generateDockerfile() {
        if (FileUtil.exist(dockerfile)) {
            String str = this.readFile("Dockerfile");
            str = StrUtil.replace(str, "${server.port}", serverPort);
            str = StrUtil.replace(str, "${project.build.finalName}", finalName);
            FileUtil.writeUtf8String(str, dockerfile);
        }
    }

    public void generateSpring() {
        if (FileUtil.exist(springSh)) {
            String str = this.readFile("springboot.sh");
            str = StrUtil.replace(str, "${project.packaging}", packaging);
            str = StrUtil.replace(str, "${project.build.finalName}", finalName);
            FileUtil.writeUtf8String(str, springSh);
        }
    }

    /**
     * 读取jar包中的文件
     *
     * @param file String
     * @return String
     */
    public String readFile(String file) {
        File jarPath = FileUtil.file(this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
        if (FileUtil.exist(jarPath)) {
            JarFile jarFile = null;
            try {
                this.getLog().info(String.format("read file: %s.%s", jarPath, file));
                jarFile = new JarFile(jarPath);
                JarEntry jarEntry = jarFile.getJarEntry(file);
                InputStream input = jarFile.getInputStream(jarEntry);
                return IoUtil.read(input, StandardCharsets.UTF_8);
            } catch (IOException e) {
                this.getLog().info(e.getMessage(), e);
            } finally {
                IoUtil.close(jarFile);
            }
        }
        return StrUtil.EMPTY;
    }

}
